// 
//  step.js

var Point = function(x, y) {
	return {
		x: x,
		y: y
	};
};

function Rect(x, y, w, h) {
	return {
		x: x,
		y: y,
		width: w,
		height: h
	};
}

//  绘制圆形
function drawCircle(x, y, w, h, color, lineWidth) {
	var r = h / 2;
	cxt.beginPath();
	cxt.moveTo(x + r, y);
	cxt.arcTo(x + w, y, x + w, y + h, r);
	cxt.arcTo(x + w, y + h, x, y + h, r);
	cxt.arcTo(x, y + h, x, y, r);
	cxt.arcTo(x, y, x + w, y, r);
	cxt.closePath();
	cxt.strokeStyle = color || 'black';
	cxt.lineWidth = lineWidth || 2;
	cxt.stroke();
}

function drawCircleTxt(x, y, w, h, color, txt, icon){
	if (txt) {
		cxt.font = "bold 12px 微软雅黑";
		var txtWidth = ctx.measureText(txt).width / 2 - 18; //测量宽度
		cxt.fillText(txt, x - txtWidth, y -4 , 100); // 绘制文字
	}
}

//绘制圆形
function drawIconCircle(x, y, w, h, color, txt, icon) {
	drawCircle(x, y, w, h, color, 4);
	cxt.fillStyle = "#fff";
	cxt.fill();
	cxt.font = "normal 26px FontAwesome";
	cxt.fillStyle = color;
	var icon = document.getElementById(icon).textContent
	cxt.fillText(icon, x + 4, y + 24, 100); // 绘制图标
	
	drawCircleTxt(x, y, w, h, color, txt, icon);
}

//绘制 定时边界事件
function drawBoundaryTimer(x, y, w, h, color, txt) {
	drawCircle(x, y, w, h, color, 2);
	cxt.fillStyle = "#fff";
	cxt.fill();
	cxt.font = "normal 26px FontAwesome";
	cxt.fillStyle = color;
	var icon = document.getElementById("timerIcon").textContent
	cxt.fillText(icon, x + 4, y + 25, 100); // 绘制图标
	drawCircleTxt(x, y, w, h, color, txt, icon);
}

//绘制 定时开始节点
function drawStartSignalEvent(x, y, w, h, color, txt) {

	drawCircle(x, y, w, h, color, 4);
	cxt.fillStyle = "#fff";
	cxt.fill();
	cxt.font = "normal 40px FontAwesome";
	cxt.fillStyle = color;
	var icon = document.getElementById("upIcon").textContent
	cxt.fillText(icon, x + 4, y + 25, 100); // 绘制图标
	drawCircleTxt(x, y, w, h, color, txt, icon);
}

//绘制 结束错误事件
function drawEndErrorEvent(x, y, w, h, color, txt) {
	
	drawCircle(x, y, w, h, color, 4);
	cxt.fillStyle = "#fff";
	cxt.fill();
	cxt.font = "normal 23px FontAwesome";
	cxt.fillStyle = color;
	var icon = document.getElementById("endErrorIcon").textContent
	cxt.fillText(icon, x + 6, y + 23, 100); // 绘制图标
	drawCircleTxt(x, y, w, h, color, txt, icon);
}
//绘制 错误边界事件
function drawBoundaryErrorEvent(x, y, w, h, color, txt) {
	
	drawCircle(x, y, w, h, color, 4);
	cxt.fillStyle = "#fff";
	cxt.fill();
	cxt.font = "normal 23px FontAwesome";
	cxt.fillStyle = color;
	var icon = document.getElementById("boundaryErrorIcon").textContent
	cxt.fillText(icon, x + 9, y + 24, 100); // 绘制图标
	drawCircleTxt(x, y, w, h, color, txt, icon);
}
//绘制 错误边界事件
function drawEndTerminateEvent(x, y, w, h, color, txt) {
	
	drawCircle(x, y, w, h, color, 6);
	cxt.fillStyle = "#fff";
	cxt.fill();
	cxt.font = "normal 26px FontAwesome";
	cxt.fillStyle = color;
	var icon = document.getElementById("endIcon").textContent
	cxt.fillText(icon, x + 4, y + 24, 100); // 绘制图标
	drawCircleTxt(x, y, w, h, color, txt, icon);
}

//绘制 信号边界事件
function drawBoundarySignalEvent(x, y, w, h, color, txt) {
	
	drawCircle(x, y, w, h, color, 1);
	var sub = 8;
	drawCircle(x + sub/2, y + sub/2, w-sub, h-sub, color, 1);
	cxt.fillStyle = "#fff";
	cxt.fill();
	cxt.font = "normal 32px FontAwesome";
	cxt.fillStyle = color;
	var icon = document.getElementById("upIcon").textContent
	cxt.fillText(icon, x + 6, y + 23, 100); // 绘制图标
	drawCircleTxt(x, y, w, h, color, txt, icon);
}

// 绘制 圆角矩形
function drawRoundedRect(rect, r) {
	cxt.lineWidth = 1;
	var ptA = Point(rect.x + r, rect.y);
	var ptB = Point(rect.x + rect.width, rect.y);
	var ptC = Point(rect.x + rect.width, rect.y + rect.height);
	var ptD = Point(rect.x, rect.y + rect.height);
	var ptE = Point(rect.x, rect.y);

	ctx.beginPath();

	ctx.moveTo(ptA.x, ptA.y);
	ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, r);
	ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, r);
	ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, r);
	ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, r);

	ctx.stroke();
}

// 菱形
function drawRhombus(x, y, l, txt, color) {
	cxt.beginPath();
	cxt.moveTo(x, y + l);
	cxt.lineTo(x - l * 2, y);
	cxt.lineTo(x, y - l);
	cxt.lineTo(x + l * 2, y);
	cxt.closePath();
	cxt.fillStyle = color;
	if (txt) {
		cxt.font = "bold 12px 微软雅黑";
		cxt.fillText(txt, x + l / 2, y + l, 100); // 绘制文字
	}
	cxt.stroke();
}

/**
 */
function drawPool(x, y, w, h, txt, icon, color) {
	this.flag = "step";
	this.h = h;
	this.w = w;
	this.x = x;
	this.y = y;
	cxt.strokeStyle = color || 'black';
	
	rect(x, y, w, h, color);
	
	if (txt) {
		cxt.font = "bold 12px 微软雅黑";
		var ang = -90 * Math.PI / 180;
		var centerX = x + 15;
		var centerY = y + h / 2 ;
		cxt.beginPath();
		
			ctx.translate(centerX, centerY);
			ctx.rotate(ang);
		
		cxt.fillStyle = color;
		cxt.strokeStyle = color;
		cxt.fillText(txt, 0, 0); // 绘制文字 这里的0和0 搞了我好久

			ctx.rotate(-ang);
			ctx.translate(-centerX, -centerY);
		
		cxt.closePath();
		cxt.stroke();
	}
}

function rect(x, y, w, h, color){
	cxt.lineWidth = 1;
	cxt.strokeStyle = color || 'black';
	 //描边矩形
    ctx.strokeRect(x, y, w, h);
}


// 并行网关
function drawParallelGateway(x, y, txt, color) {
	var l = 20;
	x = x + l;
	y = y + l;
	drawGateWay(x, y, l, txt, color);
	drawJia(x, y, l / 2 , color);
}

// 并行条件网关
function drawInclusiveGateway(x, y, txt, color) {
	var l = 20;
	x = x + l;
	y = y + l;
	drawGateWay(x, y, l, txt, color);
	x = x - l/2;
	y = y - l/2;
	drawCircle(x, y, l, l, color ,2);
}

// 分支网关
function drawExclusiveGateway(x, y, txt, color) {
	var l = 20;
	x = x + l;
	y = y + l;
	drawGateWay(x, y, l, txt, color);
	drawXX(x, y, l / 2 - 2, color);
}

// 网关
function drawGateWay(x, y, l, txt, color) {
	cxt.beginPath();
	cxt.moveTo(x, y + l);
	cxt.lineTo(x - l, y);
	cxt.lineTo(x, y - l);
	cxt.lineTo(x + l, y);
	cxt.closePath();
	cxt.fillStyle = color;
	cxt.strokeStyle = color;
	if (txt) {
		cxt.font = "bold 12px 微软雅黑";
		cxt.fillText(txt, x + l / 2, y + l, 100); // 绘制文字
	}
	cxt.stroke();
	x = x;
	y = y;
}

/**
 * 子流程
 * @param {Object} x
 * @param {Object} y
 */
function drawSubProcess(x, y, w, h, txt, color) {
	this.h = h;
	this.w = w;
	this.x = x;
	this.y = y;
	cxt.strokeStyle = color || 'black';
	if (txt) {
		//    	cxt.font = "normal 14px 微软雅黑";
		cxt.font = "bold 12px 微软雅黑";
		cxt.fillText(txt, x + 10, y + 20, 100); // 绘制文字
	}
	var rect = new Rect(x, y, this.w, this.h);
	drawRoundedRect(rect, 5);
}

/**
 * 外部子流程
 * @param {Object} x
 * @param {Object} y
 */
function drawCallActivity(x, y, w, h, txt, color) {
	drawSubProcess(x, y, w, h, txt, color);
	// 画一个加号
	cxt.font = "bold 18px FontAwesome";
	cxt.fillStyle = color;
	var icon = document.getElementById("plusIcon").textContent
	cxt.fillText(icon, x + w/2-8, y + h - 5, 100); // 绘制文字
}


// 画注释
function drawTextAnnotation(x, y, w, h, txt, color) {
	var arrow = new Arrow(x, y, x, y+h);
	arrow.setColor(color);
	arrow.draw(ctx);
	
	arrow = new Arrow(x, y, x+20, y);
	arrow.setColor(color);
	arrow.draw(ctx);
	
	arrow = new Arrow(x, y+h, x+20, y+h);
	arrow.setColor(color);
	arrow.draw(ctx);
	
	if (txt) {
		cxt.font = "bold 12px 微软雅黑";
		cxt.fillText(txt, x + 10, y + h/2, 100); // 绘制文字
	}
	
}

// 画X
function drawXX(x, y, w, color) {
	var startX = x - w;
	var startY = y - w;
	var endX = x + w;
	var endY = y + w;

	var arrow = new Arrow(startX, startY, endX, endY);
	arrow.setColor(color);
	arrow.draw(ctx);

	var arrow = new Arrow(startX, endY, endX, startY);
	arrow.setColor(color);
	arrow.draw(ctx);
}

// 画+
function drawJia(x, y, w, color) {
	
	var arrow = new Arrow(x-w, y, x+w, y);
	arrow.setColor(color);
	arrow.draw(ctx);
	
	var arrow = new Arrow(x, y-w, x, y+w);
	arrow.setColor(color);
	arrow.draw(ctx);
}


//画文字 沿着线
function draLineTxt(xoffset, yoffset, flowElement, flowLocation, stackColorJson) {
	if(!flowElement){
		return;
	}
	var outgoingFlows = flowElement.outgoingFlows || [];
	var incomingFlows = flowElement.incomingFlows || [];
	outgoingFlows.pushAll(incomingFlows);
	for (var k = 0; k < outgoingFlows.length; k++) {
		var outgoingFlow = outgoingFlows[k];
		var name = outgoingFlow.name;
		if (!outgoingFlow.id) {
			continue;
		}
		var flows = flowLocation[outgoingFlow.id];
		var flowFrom = flows[0];
		var flowTo = flows[1];
		if (name) {
			// 获取颜色
			var color = stackColorJson[outgoingFlow.id] || Color.DEFAULT;
			drawTxt(flowFrom.x - xoffset, flowFrom.y - yoffset, flowTo.x - xoffset, flowTo.y - yoffset, name, color);
		}
	}
}
// 画文字 沿着线
function drawTxt(x1, y1, x2, y2, txt, color) {
	var deg = getAngle(x1, y1, x2, y2);
	var txtWidth = ctx.measureText(txt).width / 2; //测量宽度
	
	var ofy = Math.abs(y2-y1)/2;
	var ofx = Math.abs(x2-x1)/2;
	
	var startX = x1;
	var startY = y1;
	if (deg == 0) {
		startX = x1 + ofx - txtWidth/2 - 5;
		startY = y1 - 5;
	} else if (deg > 0 && deg < 90) {
		deg = - deg;
		startX = x1 + ofx - txtWidth/2 - 10;
		startY = y1 - ofy - 5;
	} else if ( deg == 90) {
		deg = - deg;
		startX = x1 - 10;
		startY = y1 - ofy + txtWidth/2;
	} else if (deg > 90 && deg <= 180) {
		deg = (180 - deg);
		startX = x2 + ofx - txtWidth/2 - 5;
		startY = y2 + ofy - 10;
	} else if (deg > 180 && deg < 270) {
		deg = - (180 + deg);
		startX = x1 - ofx - txtWidth/2;
		startY = y1 + ofy + txtWidth/2 - 10;
	} else if (deg == 270) {
		deg = -(360 - deg);
		startX = x2 - 5;
		startY = y2 - ofy + txtWidth/2 + 5;
	} else {
		deg = (360 - deg);
		startX = x1 + ofx - txtWidth/2 + 15;
		startY = y1 + ofy - 5;
	}
	var ang = deg * Math.PI / 180;
	var centerX = startX;
	var centerY = startY;
	//    var ang = 90 * Math.PI/180;
	cxt.beginPath();
	
		ctx.translate(centerX, centerY);
		ctx.rotate(ang);
	
	cxt.fillStyle = color;
	cxt.strokeStyle = color;
	cxt.font = "normal 12px FontAwesome";
	cxt.fillText(txt, 0, 0); // 绘制文字 这里的0和0 搞了我好久

		ctx.rotate(-ang);
		ctx.translate(-centerX, -centerY);
	
	cxt.closePath();
	cxt.stroke();
}

/**
 * 圆角矩形开始对象
 * @param {Object} x
 * @param {Object} y
 */
function Start(x, y, w, h) {
	this.h = h;
	this.w = w;
	this.x = x;
	this.y = y;
	drawCircle(x - this.w / 2, y - this.h / 2, this.w, this.h);
}


/**
 * 矩形步骤对象
 * @param {Object} x
 * @param {Object} y
 */
function Step(x, y, w, h, txt, icon, color) {
	this.flag = "step";
	this.h = h;
	this.w = w;
	this.x = x;
	this.y = y;
	cxt.strokeStyle = color || 'black';
	// ctx.measureText(this.icon.text);   测量宽度
	if (icon) {
		//    	cxt.font = "normal 14px 微软雅黑";
		cxt.font = "bold 18px FontAwesome";
		cxt.fillStyle = color;
		var icon = document.getElementById(icon).textContent
		cxt.fillText(icon, x + 5, y + 19, 100); // 绘制文字
	}
	if (txt) {
		//    	cxt.font = "normal 14px 微软雅黑";
		cxt.font = "bold 12px 微软雅黑";
		var txtWidth = (w - ctx.measureText(txt).width) / 2;
		cxt.fillText(txt, x + txtWidth, y + h / 2 + 10, 100); // 绘制文字
	}
	var rect = new Rect(x, y, this.w, this.h);
	drawRoundedRect(rect, 5);
}

/**
 * 菱形条件对象
 * @param {Object} x
 * @param {Object} y
 */
function Condition(x, y) {
	this.flag = "condition";
	this.l = 30;
	this.x = x;
	this.y = y;
	drawRhombus(x, y, this.l);
}

Start.prototype.drawBottomToTop = function(obj) {
	if (obj.flag == "step") {
		var arrow = new Arrow(this.x, this.y + this.h / 2, obj.x, obj.y - obj.h / 2);
		arrow.drawBottomToTop(cxt);
	} else if (obj.flag == "condition") {
		var arrow = new Arrow(this.x, this.y + this.h / 2, obj.x, obj.y - obj.l);
		arrow.drawBottomToTop(cxt);
	}
}

Step.prototype.drawBottomToTop = function(obj) {
	if (obj.flag == "step") {
		var arrow = new Arrow(this.x, this.y + this.h / 2, obj.x, obj.y - obj.h / 2);
		arrow.drawBottomToTop(cxt);
	} else if (obj.flag == "condition") {
		var arrow = new Arrow(this.x, this.y + this.h / 2, obj.x, obj.y - obj.l);
		arrow.drawBottomToTop(cxt);
	}
}

Condition.prototype.drawBottomToTop = function(obj) {
	if (obj.flag == "step") {
		var arrow = new Arrow(this.x, this.y + this.l, obj.x, obj.y - obj.h / 2);
		arrow.drawBottomToTop(cxt);
	} else if (obj.flag == "condition") {
		var arrow = new Arrow(this.x, this.y + this.l, obj.x, obj.y - obj.l);
		arrow.drawBottomToTop(cxt);
	}
}

Condition.prototype.drawRightToTop = function(obj) {
	if (obj.flag == "step") {
		var arrow = new Arrow(this.x + this.l * 2, this.y, obj.x, obj.y - obj.h / 2);
		arrow.drawLeftOrRightToTop(cxt);
	} else if (obj.flag == "condition") {
		var arrow = new Arrow(this.x + this.l * 2, this.y, obj.x, obj.y - obj.l);
		arrow.drawLeftOrRightToTop(cxt);
	}
}

Condition.prototype.drawLeftToTop = function(obj) {
	if (obj.flag == "step") {
		var arrow = new Arrow(this.x - this.l * 2, this.y, obj.x, obj.y - obj.h / 2);
		arrow.drawLeftOrRightToTop(cxt);
	} else if (obj.flag == "condition") {
		var arrow = new Arrow(this.x - this.l * 2, this.y, obj.x, obj.y - obj.l);
		arrow.drawLeftOrRightToTop(cxt);
	}
}

Condition.prototype.drawRightToLeft = function(obj) {
	if (obj.flag == "step") {
		var arrow = new Arrow(this.x + this.l * 2, this.y, obj.x - this.w / 2, obj.y);
		arrow.drawLeftToRightOrRightToLeft(cxt);
	} else if (obj.flag == "condition") {
		var arrow = new Arrow(this.x + this.l * 2, this.y, obj.x - this.l * 2, obj.y);
		arrow.drawLeftToRightOrRightToLeft(cxt);
	}
}

Condition.prototype.drawLeftToRight = function(obj) {
	if (obj.flag == "step") {
		var arrow = new Arrow(this.x - this.l * 2, this.y, obj.x + this.w / 2, obj.y);
		arrow.drawLeftToRightOrRightToLeft(cxt);
	} else if (obj.flag == "condition") {
		var arrow = new Arrow(this.x - this.l * 2, this.y, obj.x + this.l * 2, obj.y);
		arrow.drawLeftToRightOrRightToLeft(cxt);
	}
}

function getAngle(x1, y1, x2, y2) {
	var x = x1 - x2,
		y = y1 - y2;
	if (!x && !y) {
		return 0;
	}
	//    var angle = (180+Math.abs(Math.atan2(y, x)) / Math.PI ) % 360
	var angle = Math.atan2(y2 - y1, x2 - x1);
	angle = -angle * 180 / Math.PI;
	if (angle < 0) {
		angle = angle + 360;
	}
	return angle;
}

function getFlowElementsJson(flowElements,imageInfo){
	if(!flowElements){
		return;
	}
	var flowElementJson = imageInfo.flowElementJson || {};
	var boundaryEvents = imageInfo.boundaryEvents || [];
	
	for(var i = 0 ; i < flowElements.length ; i++){
		var flow = flowElements[i];
		flowElementJson[flow.id] = flow;
		
		boundaryEvents.pushAll(flow.boundaryEvents || []);
		imageInfo.boundaryEvents = boundaryEvents;
		imageInfo.flowElementJson = flowElementJson;
		
		var sub = flow.flowElements;
		if( sub && sub.length > 0){
			getFlowElementsJson(sub,imageInfo)
		}
	}
}

function getNodeType(nodeType,i){
	
	if(nodeType){
		return nodeType;
	}
	if(i.indexOf("Pool")>=0){
		nodeType = "pool";
	}
	if(i.indexOf("Lane")>=0){
		nodeType = "lane";
	}
	if(i.indexOf("StartNoneEvent")>=0){
		nodeType = "startEvent";
	}
	if(i.indexOf("TextAnnotation")>=0){
		nodeType = "textAnnotation";
	}
	if(i.indexOf("EndNoneEvent")>=0){
		nodeType = "endEvent";
	}
	if(i.indexOf("SubProcess")>=0){
		nodeType = "subProcess";
	}
	if(i.indexOf("CallActivity")>=0){
		nodeType = "callActivity";
	}
	if(i.indexOf("UserTask15")>=0){
		nodeType = "userTask";
	}
	if(i.indexOf("ServiceTask")>=0){
		nodeType = "serviceTask";
	}
	if(i.indexOf("ExclusiveGateway")>=0){
		nodeType = "exclusiveGateway";
	}
	if(i.indexOf("ParallelGateway")>=0){
		nodeType = "parallelGateway";
	}
	if(i.indexOf("InclusiveGateway")>=0){
		nodeType = "inclusiveGateway";
	}
	
	if(i.indexOf("StartTimer")>=0){
		nodeType = "startTimer";
	}
	if(i.indexOf("BoundaryTimer")>=0){
		nodeType = "boundaryTimer";
	}
	if(i.indexOf("CatchTimer")>=0){
		nodeType = "catchTimer";
	}
	if(i.indexOf("StartSignal")>=0){
		nodeType = "startSignal";
	}
	if(i.indexOf("BoundarySignal")>=0){
		nodeType = "boundarySignal";
	}
	if(i.indexOf("CatchSignal")>=0){
		nodeType = "catchSignal";
	}
	if(i.indexOf("ThrowSignal")>=0){
		nodeType = "throwSignal";
	}
	if(i.indexOf("EndError")>=0){
		nodeType = "endError";
	}
	if(i.indexOf("BoundaryError")>=0){
		nodeType = "boundaryError";
	}
	if(i.indexOf("EndTerminate")>=0){
		nodeType = "endTerminate";
	}
	return nodeType;
}
